from config import config_singleton
import time
import socket
import struct
from utils import sys_logger
import queue
import threading
from utils import sys_logger
from utils import BaseClient


class TcpClient(BaseClient):
    """
    """

    def __init__(self, ip, port, queue_maxsize) -> None:

        self.ip = ip
        self.port = port
        self._recv_queue = queue.Queue(maxsize=queue_maxsize)
        self._send_queue = queue.Queue(maxsize=queue_maxsize)
        self.sock = None
        self.need_stop = False
        self.connected = False
        self.lock = threading.Lock()
        self.byte_cnt = 0

    def connect(self):
        """connect to server"""
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            self.sock.connect((self.ip, self.port))
            self.connected = True
            sys_logger.info(f"Connected to server. IP:{self.ip}, PORT:{self.port}.")
        except socket.error as e:
            sys_logger.error(
                f"Failed to connect to {self.ip}:{self.port}: {e}")
            self.connected = False

    def disconnect(self):
        """Disconnect from server"""
        if self.sock:
            self.sock.close()
            self.connected = False
            self.sock = None
        
        sys_logger.info("Disconnected from server.")

    def do_send(self):

        while not self.need_stop and self.connected:
            try:
                data = self._send_queue.get()

                if data is None:
                   continue 

                self.sock.send(data)
                self.byte_cnt += len(data)      # 发送计数

            except socket.error as e:
                sys_logger.error(f"Failed to send data: {e}. Total send {self.byte_cnt} bytes")
                self.disconnect()

        if self.need_stop:
            sys_logger.info(f"Client shutting down, Total send {self.byte_cnt} bytes.")
    

    def do_receive(self):
        """
        TODO:接收线程,暂时未实现
        """
        return super().do_receive()
        

    def put_send_data(self, data):
        """Add data to the send queue"""
        if not self.need_stop and self.connected:
            self._send_queue.put(data)

    def get_recv_data(self):
        """Get data from the receive queue"""
        return self._recv_queue.get()

    def stop(self):
        """
        """
        self.need_stop = True
        self.put_send_data(None)
        self.disconnect()
        
        


class TcpServer(BaseClient):
    """tcp sever"""

    def __init__(self, host='127.0.0.1', port=12345, queue_maxszie=1024) -> None:
        super.__init__()
        self.host = host
        self.port = port
        self._recv_queue = queue.Queue(maxsize=queue_maxszie)
        self._send_queue = queue.Queue(maxsize=queue_maxszie)
        self.clients = []
        self.server_sock = None
        self.need_stop = False
        self.accept_thread = None

    def start_server(self):
        """创建监听的服务"""
        self.server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_sock.bind((self.host, self.port))
        self.server_sock.listen(5)
        sys_logger.info(f"Server started on port {self.port}")

        # start a thread to accept incoming connections
        self.accept_thread = threading.Thread(target=self.accept_client)
        self.accept_thread.start()


    def accept_client(self):
        while not self.need_stop:
            client_sock, addr = self.server_sock.accept()
            self.clients.append(client_sock)
            sys_logger.info(f"Accepted connection from {addr}")


    def do_send(self):
        """发送线程"""
        while not self.need_stop:
            try:
                data = self._send_queue.get()
                for client_sock in self.clients:
                    client_sock.sendall(data)
            except socket.error as e:
                sys_logger.error(
                    f"Failed to send data to one of the clients: {e}")

    
    def do_receive(self):
        """
        TODO：后续补充
        """
        return super().do_receive()


    def stop(self):
        """Stop the server and close all client connections"""
        self.need_stop = True
        for client_sock in self.clients:
            client_sock.close()
        if self.server_sock:
            self.server_sock.close()
        if self.accept_thread:
            self.accept_thread.join()
        sys_logger.info("Server stopped")


    def put_send_data(self, data):
        """Add data to the send queue"""
        with self.lock:
            self._send_queue.put(data)


    def get_recv_data(self):
        """"Get data from the receive queue"""
        return self._recv_queue.get()

if __name__ == "__main__":
    """example"""
    client = TcpClient('127.0.0.1', 12345, 100)
    client.connect()
